#include <vector>
#include <thread>
#include <algorithm>
#include <functional>
#include <iostream>

void do_work(unsigned id)
{
    printf("%d\n", id);
}

struct Foo {
    void display_greeting() {
        std::cout << "Hello, world.\n";
    }
    void display_number(int i) {
        std::cout << "number: " << i << '\n';
    }
    int data = 7;
};


void f()
{
    std::vector<std::thread> threads;
    for(unsigned i=0;i<20;++i)
    {
        threads.push_back(std::thread(do_work,i));
    }
    std::for_each(threads.begin(),threads.end(),
        std::mem_fn(&std::thread::join));
}

auto greet = std::mem_fn(&Foo::display_greeting);

int main()
{
    Foo foo;


    greet(foo);

    auto print_num = std::mem_fn(&Foo::display_number);
    print_num(foo, 42);

    auto access_data = std::mem_fn(&Foo::data);
    std::cout << "data: " << access_data(foo) << '\n';

    f();
}
